#include "tio_intf.h"
// #include "robohubscb/robohub.h"
#include "tioV3/tiov3.h"
#include "log/zlog.hh"

rtdev::TioBoardItf* rtdev::TioBoardItf::create(uint8_t type)
{
    std::unique_ptr<rtdev::TioBoardFactoryItf> factory;
    switch (type)
    {
    case ktioV3:
        factory.reset(new rtdev::TioV3Factory());
        break;
    default:
        return nullptr;
    };
    rtdev::TioBoardItf* ret = factory->create();

    return ret;
}
rtdev::TioBoardItf::TioBoardItf()
{
    sim_flag_ = 0;
    alive_watchdog_ = 0;
    alive_flag_ = false;
    last_alive_cnt_ = -1;
}

void rtdev::TioBoardItf::check_alive()
{
    bool alive = false;
    if (sim_flag_)
    {
        alive = true;
    }
    else
    {
        if (alive_watchdog_ <= 0)
        {
            alive = false;
        }
        else
        {
            alive_watchdog_--;
            alive = true;
        }
    }
    if (alive != alive_flag_)
    {
        zlog()->info("Device: {} is {}, sim={}", name(), alive ? "online" : "offline", sim_flag_);
        alive_flag_ = alive;
    }
}

int rtdev::TioBoardItf::keep_alive(int alive)
{
    if (last_alive_cnt_ != alive)
    {
        last_alive_cnt_ = alive;
        alive_watchdog_ = 1000;
        return 0;
    }
    return -1;
}
bool rtdev::TioBoardItf::is_alive() { return alive_flag_; }
bool rtdev::TioBoardItf::is_sim() { return sim_flag_ == 1; }

void rtdev::TioBoardItf::check_alive_optional()
{
    bool alive = false;
    if (sim_flag_)
    {
        alive = true;
    }
    else
    {
        for (auto it = OptionalPdoMap_.begin(); it != OptionalPdoMap_.end(); ++it)
        {
            int id = it->first;
            if (it->second.alive_watchdog <= 0)
            {
                alive = false;
            }
            else
            {
                it->second.alive_watchdog--;
                alive = true;
            }
            if (alive != it->second.alive_flag)
            {
                zlog()->info("Device: {} optional pdo {:x} is {}, sim={}", name(), it->first, alive ? "online" : "offline", sim_flag_);
                it->second.alive_flag = alive;
            }
        }
    }
}

int rtdev::TioBoardItf::keep_alive_optional(int pdo_id, int alive)
{
    auto it = OptionalPdoMap_.find(pdo_id);
    if (it == OptionalPdoMap_.end())
    {
        return -1;
    }

    if (it->second.last_alive_cnt != alive)
    {
        it->second.last_alive_cnt = alive;
        it->second.alive_watchdog = 1000;
        return 0;
    }
    return -1;
}

bool rtdev::TioBoardItf::is_alive_optional(int pdo_id)
{
    auto it = OptionalPdoMap_.find(pdo_id);
    if (it == OptionalPdoMap_.end())
    {
        return false;
    }
    return it->second.alive_flag;
}